From: Colin Walters Date: Tue, 28 Nov 2017 18:03:00 +0000 (-0500) Subject: lib/repo: Verify txn stagedir existence after locking X-Git-Tag: archive/raspbian/2022.1-3+rpi1~1^2~4^2~29^2~2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=5ef8faff9a10f055401df5265e389ba9bbb89786;p=ostree.git lib/repo: Verify txn stagedir existence after locking This squashes the last race condition I was actively hitting while running `test-concurrency.py` in a loop. The race is when process A finds a tmpdir to reuse, and goes to lock it. Meanwhile process B deletes it and unlocks the lock. Process A then succeeds at grabbing a lock, but the tmpdir is deleted. Closes: #1352 Approved by: dbnicholson --- diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 6e342125..afd56e4c 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -4904,7 +4904,16 @@ _ostree_repo_try_lock_tmpdir (int tmpdir_dfd, } else { - did_lock = TRUE; + /* It's possible that we got a lock after seeing the directory, but + * another process deleted the tmpdir, so verify it still exists. + */ + struct stat stbuf; + if (!glnx_fstatat_allow_noent (tmpdir_dfd, tmpdir_name, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return FALSE; + if (errno == 0 && S_ISDIR (stbuf.st_mode)) + did_lock = TRUE; + else + glnx_release_lock_file (file_lock_out); } *out_did_lock = did_lock;